package com.unittec.zk.provider.common;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.unittec.zk.sdk.root.common.FieldConstants;

/**
 * @author wuxinwei
 */
public class JwtTokenUtil {

    public static final String PUBKEY =
        "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdPVHOGw+yyfWKPHsFpK4T2HEk0wMIYDvSyP4W0czigIjfX6E11MPMpiX16oR9UrTp2EzJx5sHas1vihuDVYAflQZvp9s9wI0Sfu/SIZMasvkE7d+ODP+wf/Z1aCZcg/I+12wUZMYtHM9Gw+i2E64FeDZne6f3ro7tx8PzD/mGqQIDAQAB";

    private static final int ADVANCE_EXPIRE_TIME = 24 * 60 * 1000;

    private static final String PRIKEY =
        "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAN09Uc4bD7LJ9Yo8ewWkrhPYcSTTAwhgO9LI/hbRzOKAiN9foTXUw8ymJfXqhH1StOnYTMnHmwdqzW+KG4NVgB+VBm+n2z3AjRJ+79Ihkxqy+QTt344M/7B/9nVoJlyD8j7XbBRkxi0cz0bD6LYTrgV4Nmd7p/euju3Hw/MP+YapAgMBAAECgYBYazlWddpAShanuKQyDS7FH6uYW/zKTCucgleKJy8LFvOc0ktLiEz4bS6eqatpqrRDAP8vZWbAAB86hKeaRYF+X3ZWSbWbzxLVaVGcUCBgW1N2XGXuIBmPe4g9ar2PO4hoZTmvkgjcHYDK1TckCq2/CEFco0lWbb8xkszR7a15QQJBAPRFcyv1NQlGbpslhRWmsmCAqeu4BvZDQdsve5LeIjFS2hEM8iukIpg7RxcHEkkQI/uFXYscZEx8vNiQVbVrYQsCQQDn3MQvd5LBxFQr+IkUtptYYBl8K32lmHfSDZLnULtAGD1jrFcfZ1ZNP6BhBBwwZ61aSIbYP1JqJebyCEAL5m+bAkAOyD0mBdrFyutanDSnkMTurhqaVzKkqIFNwFvcEXFERt1Hdt8Y4P/u8ndk31qt7TogOHvmtTsknc/X0zQ8nFjtAkEAvq5vZX4X4mTcuECwM6mtffOiYdy+e1Y1jDj/jF53cFG/At6z066/ac4ezkp8CE7rYOluhB8nXwaGtJuWWHMNawJAedTi1UBErWn8osxubPpGnaJvJn5nyBdikP51S6CcTACvJyNCBDv51LGM1Nv6xyaWv58RHsPgGJZhVv25IPrGtQ==";

    public static String createToken(String userId, String userName, String tenantId, String appCode, String appId)
        throws Exception {
        // 签发时间
        Date istDate = new Date();
        // 设置过期时间
        Calendar nowTime = Calendar.getInstance();
        nowTime.add(Calendar.HOUR, 24);
        Date expiresDate = nowTime.getTime();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("alg", "HS256");
        map.put("typ", "JWT");
        String token = JWT.create().withHeader(map).withClaim(FieldConstants.LOGIN_USER, userId)
            .withClaim(FieldConstants.LOGIN_USER_NAME, userName).withClaim(FieldConstants.APP_ID, appId)
            .withClaim(FieldConstants.TENANT_ID, tenantId).withClaim(FieldConstants.APP_CODE, appCode)
            .withSubject("subject").withExpiresAt(expiresDate).withIssuedAt(istDate)
            .sign(Algorithm.RSA256(null, RSAEncrypt.getPrivateKey(PRIKEY)));
        return token;
    }

    public static Map<String, Claim> verifyToken(String token) throws Exception {
        JWTVerifier verifier = JWT.require(Algorithm.RSA256(RSAEncrypt.getPublicKey(PUBKEY), null)).build();
        DecodedJWT jwt = null;
        try {
            jwt = verifier.verify(token);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return jwt.getClaims();
    }

    public static Date getExpirationDateFromToken(String token) {
        return JWT.decode(token).getExpiresAt();
    }

    public static boolean checkToken(String token) {
        return JwtTokenUtil.getExpirationDateFromToken(token).getTime()
            - System.currentTimeMillis() >= ADVANCE_EXPIRE_TIME;
    }

}
